import { useRef, useState } from 'react'
import { useDrop } from 'react-dnd'
import { Empty, Form } from 'antd'
import classnames from 'classnames'
import DesignFormItem from './components/DesignFormItem'

/** 获取 DOM 元素的中间位置 */
const getElementMiddleY = (el) => {
  const elRect = el.getBoundingClientRect();
  return elRect.top + elRect.height / 2
}

const SchemaFormDesign = ({
  focusItem,
  items = [],
  onAction,
}) => {

  const [form] = Form.useForm()

  const boxRef = useRef(null)
  const [holdIndex, setHoldIndex] = useState(null)

  // 
  const handleDropFromPalette = (paletteItem, index) => {
    onAction({
      type: 'create',
      paletteItem: paletteItem,
      insertIndex: index
    })
  }

  const getHoldIndex = (y) => {
    let result
    const items = boxRef.current.children
    if (items.length > 0) {
      for (let i = 0; i < items.length; i++) {
        const minY = getElementMiddleY(items[0])
        const maxY = getElementMiddleY(items[items.length - 1])
        if (y < minY) {
          result = 0
        } else if (y > maxY) {
          result = items.length
        } else {
          for (let i = 0; i < items.length; i++) {
            if (i !== 0) {
              const space = [getElementMiddleY(items[i]), getElementMiddleY(items[i - 1])]
              if (y > space[1] && y < space[0]) {
                result = i
              }
            }
          }
        }
      }
    } else {
      result = 0
    }
    return result
  }

  // 拖拽移动表单位置
  const handleMoveItem = (y, id) => {
    const index = items.findIndex(el => el.id === id)
    const elList = boxRef.current.children
    for (let i = 0; i < elList.length; i++) {
      if (i !== index) {
        if (i === items.length - 1) {
          const maxY = getElementMiddleY(elList[i])
          if (y > maxY) {
            onAction({
              type: 'move',
              fromIndex: index,
              toIndex: i
            })
          }
        } else if (i === 0) {
          const maxY = getElementMiddleY(elList[i])
          if (y < maxY) {
            onAction({
              type: 'move',
              fromIndex: index,
              toIndex: i
            })
          }
        } else {
          let space = []
          if (i > index) { // 向下
            space = [getElementMiddleY(elList[i]), getElementMiddleY(elList[i + 1])]
          } else if (i < index) { // 向上
            space = [getElementMiddleY(elList[i - 1]), getElementMiddleY(elList[i])]
          }
          if (y < space[1] && y > space[0]) {
            onAction({
              type: 'move',
              fromIndex: index,
              toIndex: i
            })
          }
        }
      }
    }
  }

  const [{ isOver }, drop] = useDrop({
    accept: 'FORM_DESIGNER',
    collect: (monitor) => {
      return {
        isOver: monitor.isOver(),
      };
    },
    hover(item, monitor) {
      const { y } = monitor.getClientOffset();
      if (item.dragType === 'design') {
        handleMoveItem(y, item.designItem.id)
      } else if (item.dragType === 'palette') {
        setHoldIndex(getHoldIndex(y))
      }
    },
    drop(item) {
      if (item.dragType === 'palette') {
        handleDropFromPalette(item.paletteItem, holdIndex)
      }
      setHoldIndex(null)
    }
  })

  const isHoldShow = (i) => {
    return isOver && holdIndex === i
  }

  const isLastHoldShow = () => {
    return isOver && holdIndex === items.length
  }

  return <Form
    labelCol={{ span: 6 }}
    style={{ width: '100%', height: '100%' }}
    form={form}
  >
    <div
      className="form-design-box"
      ref={drop}
    >
      <div
        className={classnames('form-design-box-handle', {
          active: focusItem === null
        })}
        onClick={() => {
          onAction({
            type: 'focus'
          })
        }}
      >
        {items.length === 0 && <Empty description="暂无表单"></Empty>}
      </div>
      <div
        className="form-design-inner-box"
        onClick={() => {
          onAction({
            type: 'focus'
          })
        }}
      >
        <div ref={boxRef}>
          {
            items.map((el, i) => {
              return <div key={el.id}>
                <div
                  style={{
                    display: isHoldShow(i) ? 'block' : 'none'
                  }}
                  className="dnd-design-item-hold"
                ></div>
                <DesignFormItem
                  item={el}
                  index={i}
                  isFocus={focusItem && focusItem.id === el.id}
                  onAction={onAction}
                  onChangeDefaultValue={(obj) => {
                    form.setFieldsValue(obj)
                  }}
                ></DesignFormItem>
              </div>
            })
          }
        </div>
        {
          <div
            className="dnd-design-item-hold last"
            style={{
              display: isLastHoldShow() ? 'block' : 'none',
              marginBottom: 10
            }}
          ></div>
        }
      </div>
    </div>
  </Form>
}

export default SchemaFormDesign